import io
import logging

from django.contrib.auth.models import User
from django.http import HttpResponse
from django.shortcuts import render
from django.views import View
from django_redis import get_redis_connection
from rest_framework.decorators import action
from rest_framework.mixins import RetrieveModelMixin
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet, ReadOnlyModelViewSet, ModelViewSet
from rest_framework.status import HTTP_404_NOT_FOUND, HTTP_400_BAD_REQUEST, HTTP_500_INTERNAL_SERVER_ERROR
from rest_framework_extensions.cache.mixins import CacheResponseMixin
from rest_framework.permissions import IsAuthenticated

from config.dbs.redisConfig import LOGIN_KEY_TEMPLATE, EXPIPE_TIME
from config.fastdfsConfig import FASTDFS_SERVER_DOMAIN
from users.models import UserDetail, Area, Address
from users.serializers import UserSerializer, UserDetailSerializer, AreaSerializer, ParentSerializer, AddressSerializer
from users.utils import ActiveUserPermission
from utils.permissions import create_auto_user, update_auto_user, destroy_auto_user
from utils.verifyUtil import ImageVerify

from fdfs_client.client import Fdfs_client, get_tracker_conf


# Create your views here.
class ImageVerifyView(View):
    """
    图片验证码
    """

    def get(self, request, uuid):
        image_verify = ImageVerify()
        image, code = image_verify.verify_code()  # 图片验证码(响应给用户),答案(存起来)

        # 创建一个字节流临时文件
        img_bytes = io.BytesIO()
        # 将图片数据存入
        image.save(img_bytes, format='PNG')
        # 从字节文件中获取内容
        image_bytes = img_bytes.getvalue()

        # 将uuid对应验证码答案存到redis中
        cache = get_redis_connection(alias='verify_code')  # 获取连接对象
        cache.set(LOGIN_KEY_TEMPLATE % uuid, code, EXPIPE_TIME)

        return HttpResponse(image_bytes, content_type='image/png')


# 导入日志器
logger = logging.getLogger(__name__)

tracker_path = get_tracker_conf('utils/fastdfs/client.conf')
client = Fdfs_client(tracker_path)


class UserViewSet(RetrieveModelMixin, GenericViewSet):
    permission_classes = [ActiveUserPermission]
    queryset = User.objects.filter(is_active=1)
    serializer_class = UserSerializer

    def update(self, request, pk):
        # 查看用户
        pass
        try:
            user = User.objects.get(id=pk)
        except User.DoesNotExist:
            return Response(status=HTTP_404_NOT_FOUND)
        # 反序列化
        user_serializer = self.get_serializer(user, data=request.data)
        # 校验
        user_serializer.is_valid(raise_exception=True)
        # 保存
        user_serializer.save()

        request.data['user'] = request.data['id']
        # 详情部分 不一定用户已经存在详情表 判断
        user_detail = request.data['userdetail']
        if hasattr(user, 'userdetail'):
            # 有详情表 那么得到详情表 save修改
            user_detail_serializer = UserDetailSerializer(user.userdetail, data=user_detail)
        else:
            # 没有详情表 那么创建并save保存
            user_detail_serializer = UserDetailSerializer(data=user_detail)
        user_detail_serializer.is_valid(raise_exception=True)
        user_detail_serializer.save()

        user_serializer.data['userdetail'] = user_detail_serializer.data
        return Response(user_serializer.data)

    @action(methods=['post'], detail=True)
    def avatar(self, request, pk):
        # 获取用户
        try:
            user = User.objects.get(id=pk)
        except User.DoesNotExist:
            return Response(status=HTTP_404_NOT_FOUND)
        # 获取请求中的文件数据，处理文件
        files = request.FILES.get('file')
        if not files or files.content_type not in ('image/jpeg', 'image/gif', 'image/png'):
            logger.info('前端图片获取失败')
            return Response(status=HTTP_400_BAD_REQUEST)
        try:
            image_ext_name = files.name.split('.')[-1]
        except Exception as e:
            logger.info('图片后缀名异常：{}'.format(e))
            image_ext_name = 'png'

        try:
            upload_res = client.upload_by_buffer(files.read(), file_ext_name=image_ext_name)
        except Exception as e:
            logger.info('图片上传异常：{}'.format(e))
            return Response(status=HTTP_500_INTERNAL_SERVER_ERROR)
        else:
            if upload_res.get('Status') != 'Upload successed.':
                logger.info('图片上传到FastDFS服务器失败')
                return Response(status=HTTP_500_INTERNAL_SERVER_ERROR)
            else:
                image_name = upload_res.get('Remote file_id').decode()
                image_url = FASTDFS_SERVER_DOMAIN + image_name

                # 判断一下当前用户是否有详情
                # 有,修改头像   没有,创建详情，设置头像
                if hasattr(user, 'userdetail'):
                    user_detail = user.userdetail
                    user_detail.avatar = image_url
                    user_detail.save()
                else:
                    UserDetail.objects.create(avatar=image_url, user=user)
                return Response({'data': image_url})


class AreaViewSet(CacheResponseMixin, ReadOnlyModelViewSet):
    def get_queryset(self):
        if self.action == 'list':
            return Area.objects.filter(parent=None)
        else:
            return Area.objects.all()

    def get_serializer_class(self):
        if self.action == 'list':
            return AreaSerializer
        else:
            return ParentSerializer


class AddressViewSet(ModelViewSet):
    serializer_class = AddressSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        return self.request.user.address_set.filter(is_delete=False)

    @create_auto_user
    def create(self, request, *args, **kwargs):
        if 10 <= self.get_queryset().count():
            return Response({'detail': '收货地址超出上限'}, status=HTTP_400_BAD_REQUEST)

        return ModelViewSet.create(self, request, *args, **kwargs)

    @update_auto_user(Address)
    def update(self, request, *args, **kwargs):
        return ModelViewSet.update(self, request, *args, **kwargs)

    @destroy_auto_user(Address)
    def destroy(self, request, *args, **kwargs):
        return ModelViewSet.destroy(self, request, *args, **kwargs)
